package com.zerowidth.moc.web.pay.ls;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

public class PaymentGateway {
    private Map<String, String> config;

    public PaymentGateway(Map<String, String> config) {
        this.config = config;
    }

    /**
     * 生成订单号
     */
    public String generateOrderID() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        String timestamp = dateFormat.format(new Date());
        Random random = new Random();
        int randomNumber = random.nextInt(900000) + 100000;
        return "E" + timestamp + randomNumber;
    }

    /**
     * 发起支付
     */
    public String initiatePayment(int amount) {
        try {
            String payOrderID = generateOrderID();
            int amountInCents = amount * 100;

            Map<String, String> orderData = new HashMap<>();
            orderData.put("mch_no", config.get("mch_no"));
            orderData.put("app_id", config.get("app_id"));
            orderData.put("mch_order_no", payOrderID);
            orderData.put("way_code", config.get("way_code"));
            orderData.put("amount", String.valueOf(amountInCents));
            orderData.put("currency", "cny");
            orderData.put("subject", "test");
            orderData.put("body", "test");
            orderData.put("req_time", String.valueOf(System.currentTimeMillis()));
            orderData.put("version", "1.0");
            orderData.put("sign_type", "MD5");
            orderData.put("return_url", config.get("pay_callback_url"));
            orderData.put("notify_url", config.get("pay_notify_url"));

            orderData.put("sign", generateSignature(orderData, config.get("md5_key")));

            return sendRequest(config.get("tj_url"), orderData);
        } catch (Exception e) {
            return "Failed to initiate payment. " + e.getMessage();
        }
    }

    /**
     * 发送 HTTP 请求
     */
    private String sendRequest(String url, Map<String, String> data) throws Exception {
        HttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);

        // 设置POST请求参数
        List<NameValuePair> params = new ArrayList<>();
        for (Map.Entry<String, String> entry : data.entrySet()) {
            params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        httpPost.setEntity(new UrlEncodedFormEntity(params));

        // 执行POST请求
        HttpResponse response = httpClient.execute(httpPost);
        HttpEntity responseEntity = response.getEntity();
        if (responseEntity != null) {
            return EntityUtils.toString(responseEntity);
        } else {
            return null;
        }
    }

    /**
     * 生成签名
     */
    private String generateSignature(Map<String, String> data, String secret) throws NoSuchAlgorithmException {
        // 将数据按照键名进行排序
        Map<String, String> sortedData = new TreeMap<>(data);

        // 构建待签名字符串
        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : sortedData.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (value != null && !value.isEmpty()) {
                stringBuilder.append(key).append("=").append(value).append("&");
            }
        }
        stringBuilder.append("key=").append(secret);

        // 计算 MD5 签名
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(stringBuilder.toString().getBytes());
        byte[] digest = md5.digest();

        // 将字节数组转换为十六进制字符串
        StringBuilder signature = new StringBuilder();
        for (byte b : digest) {
            signature.append(String.format("%02x", b));
        }

        return signature.toString().toUpperCase();
    }

    public static void main(String[] args) {
        // 配置参数
        Map<String, String> config = new HashMap<>();
        config.put("mch_no", "your_mch_no");
        config.put("app_id", "your_app_id");
        config.put("md5_key", "your_md5_key");
        config.put("way_code", "your_way_code");
        config.put("pay_notify_url", "your_pay_notify_url");
        config.put("pay_callback_url", "your_pay_callback_url");
        config.put("tj_url", "your_tj_url");

        // 创建支付网关实例
        PaymentGateway paymentGateway = new PaymentGateway(config);

        // 发起支付
        int amount = 100; // 金额（单位：元）
        String paymentResult = paymentGateway.initiatePayment(amount);
        System.out.println(paymentResult);
    }
}